﻿using System;
using System.Configuration;
using System.IO;
using System.Net;
using System.Threading;
using System.Windows.Forms;
using log4net;
using Matrix.MaKaYunShang.BLL;
using Matrix.MaKaYunShang.BLL.WxInterfaceFunc;
using Matrix.MaKaYunShang.Model;
using Matrix.MaKaYunShang.Model.WeChat;
using Matrix.MaKaYunShang.QrCodeCreator.Properties;

namespace Matrix.MaKaYunShang.QrCodeCreator
{
    public class QrCodeCreateThread
    {
        public Thread CreatorThread;
        private readonly ILog _fileLog = LogManager.GetLogger(typeof(QrCodeCreateThread));
        private readonly WechatInfoBLL _weChatInfoBll = new WechatInfoBLL();
        private readonly WxInterQrCodeFunc _wxInterQrCodeFunc = new WxInterQrCodeFunc();
        private readonly WechatParamQrCodeBLL _wechatParamQrCodeBll = new WechatParamQrCodeBLL();
        private readonly string _qrCodeImageFolder = ConfigurationManager.AppSettings["QrCodeImageFolder"];
        private readonly string _qrCodeImageHttpPath = ConfigurationManager.AppSettings["QrCodeImageHttpPath"];

        public delegate void FinishCreatingNewQrCode(object sender, EventArgs e);

        public event FinishCreatingNewQrCode OnEventFinishedQrCode;

        private readonly int _nTotalCreateAmount;
        private string _strAppId;
        private readonly int _nStartSceneId;

        public int NFinishCreateAmount ;
        public bool BRunning;


        public QrCodeCreateThread(int totalCreateAmount, bool running, string appId, int startSceneId)
        {
            _nTotalCreateAmount = totalCreateAmount;
            BRunning = running;
            _strAppId = appId;
            NFinishCreateAmount = 0;
            _nStartSceneId = startSceneId;
        }

        public void  CreateNewThread()
        {
            CreatorThread = new Thread(ThreadMain) {IsBackground = true};
        }

        public void StartThread()
        {
            CreatorThread.Start();
            BRunning = true;
        }

        public void StopThread()
        {
            BRunning = false;
        }

        private void ThreadMain()
        {
            try
            {

                var nSceneId = _nStartSceneId == 0 ? 1 : _nStartSceneId;
                var wechatInfo = _weChatInfoBll.GetWeChatInfoByAppId(_strAppId);
                var strAccessToken = _wxInterQrCodeFunc.GetWxToken(wechatInfo.AppId, wechatInfo.Secret, wechatInfo.WechatId);
                if (string.IsNullOrWhiteSpace(strAccessToken))
                {
                    _fileLog.Error("QrCodeCreateThread | CreateParamQrCode: Error AccessToken");
                    MessageBox.Show(Resources.ErrorAccessToken);
                    return;
                }
                var nErrorCount = 0;
                while (nSceneId <= _nTotalCreateAmount)
                {
                    try
                    {
                        if (string.IsNullOrWhiteSpace(strAccessToken))
                        {
                            nErrorCount++;
                            if (nErrorCount > 20)
                            {
                                _fileLog.Error("QrCodeCreateThread | CreateParamQrCode: Error happened to much");
                                break;
                            }
                        }

                        var qrCodeInfo = _wxInterQrCodeFunc.CreateQrCodeImage(nSceneId, wechatInfo, strAccessToken);
                        if (qrCodeInfo == null || !string.IsNullOrWhiteSpace(qrCodeInfo.ErrorMsg))
                        {
                            nErrorCount++;
                            if(qrCodeInfo != null)
                            {
                                if (qrCodeInfo.ErrorMsg.Contains("\"errcode\":") &&
                                    qrCodeInfo.ErrorMsg.Contains("\"errmsg\":"))
                                {
                                    _fileLog.Error("QrCodeCreateThread | CreateParamQrCode: Error Msg from WeChat" +
                                               qrCodeInfo.ErrorMsg);

                                    if (qrCodeInfo.ErrorMsg.Contains("40001") || qrCodeInfo.ErrorMsg.Contains("40014") || qrCodeInfo.ErrorMsg.Contains("42001"))
                                    {
                                        strAccessToken = _wxInterQrCodeFunc.GetWxToken(wechatInfo.AppId, wechatInfo.Secret, wechatInfo.WechatId);
                                        continue;
                                    }
                                }
                            }
                            else
                            {
                                if (nErrorCount > 20)
                                {
                                    _fileLog.Error("QrCodeCreateThread | CreateParamQrCode: Error happened to much");
                                    break;
                                }
                                continue;
                            }
                        }

                        var paramQrCodeInfo = _wechatParamQrCodeBll.GetModelByTicket(qrCodeInfo.Ticket);
                        int nFileNamePart;
                        if (paramQrCodeInfo != null && paramQrCodeInfo.Id > 0)
                        {
                            nFileNamePart = paramQrCodeInfo.Id;
                            paramQrCodeInfo.IsDelete = false;
                            paramQrCodeInfo.QrCodeContent = qrCodeInfo.Url;
                            paramQrCodeInfo.QrCodePath = qrCodeInfo.ImageUrl;
                            paramQrCodeInfo.QrCodeTicket = qrCodeInfo.Ticket;
                            paramQrCodeInfo.WechatInfoId = 1;
                            paramQrCodeInfo.SceneId = nSceneId;
                            _wechatParamQrCodeBll.Update(paramQrCodeInfo);
                        }
                        else
                        {
                            //保存二维码数据
                            var paramQrCodeInfoNew = new WechatParamQrCode
                            {
                                IsDelete = false,
                                QrCodeContent = qrCodeInfo.Url,
                                QrCodePath = qrCodeInfo.ImageUrl,
                                QrCodeTicket = qrCodeInfo.Ticket,
                                WechatInfoId = 1,
                                SceneId = nSceneId
                            };
                            nFileNamePart = _wechatParamQrCodeBll.Add(paramQrCodeInfoNew);
                            if (nFileNamePart > 0)
                            {
                                paramQrCodeInfoNew.Id = nFileNamePart;
                                paramQrCodeInfo = paramQrCodeInfoNew;
                            }
                        }

                        if (nFileNamePart > 0 && paramQrCodeInfo != null)
                        {
                            var strFileName = wechatInfo.WechatId + "_" + nFileNamePart;
                            var strLocalImagePath = DownloadQrCodeImage(qrCodeInfo.ImageUrl, strFileName, nFileNamePart,
                                wechatInfo.WechatId);
                            paramQrCodeInfo.LocalQrCodePath = strLocalImagePath;
                            _wechatParamQrCodeBll.Update(paramQrCodeInfo);
                        }
                    }
                    catch (Exception ex)
                    {
                        _fileLog.Error("QrCodeCreateThread | CreateParamQrCode: " + ex.StackTrace + ex.Message);
                        throw;
                    }

                    NFinishCreateAmount = nSceneId;
                    OnEventFinishedQrCode(this, new EventArgs());
                    if (nSceneId > 0 && nSceneId % 100 == 0)
                    {
                        Thread.Sleep(1000);
                    }
                    if (!BRunning)
                    {
                        break;
                    }

                    nSceneId++;
                }
            }
            catch (WxErrorMsgException ex)
            {
                _fileLog.Error("QrCodeCreateThread | ThreadMain : Exception - " + ex.Message + ex.StackTrace);
            }
            catch (Exception ex)
            {
                _fileLog.Error("QrCodeCreateThread | ThreadMain : Exception - " + ex.Message + ex.StackTrace);
            }
            BRunning = false;
            OnEventFinishedQrCode(this, new EventArgs());
        }

        private string DownloadQrCodeImage(string imageUrl, string fileName, int qrCodeId, string wechatId)
        {
            var strImageWechatFolder = _qrCodeImageFolder + "/" + wechatId;
            if (Directory.Exists(strImageWechatFolder) == false)
            {
                Directory.CreateDirectory(strImageWechatFolder);
            }

            var strSubFolder = "Image_" + (qrCodeId/1000);
            if ((qrCodeId % 1000) == 0)
            {
                strSubFolder = "Image_" + ((qrCodeId / 1000)-1);
            }


            if (Directory.Exists(strImageWechatFolder + "/" + strSubFolder) == false)
            {
                Directory.CreateDirectory(strImageWechatFolder + "/" + strSubFolder);
            }

            var strImageSavePath = strImageWechatFolder + "/" + strSubFolder + "/" + fileName + ".jpg";
            var strImageHttpPath = _qrCodeImageHttpPath + "/" + wechatId + "/" + strSubFolder + "/" + fileName + ".jpg";
            if (File.Exists(strImageSavePath))
            {
                File.Delete(strImageSavePath);
            }

            var req = (HttpWebRequest)WebRequest.Create(imageUrl);
// ReSharper disable once AssignNullToNotNullAttribute
            var img = System.Drawing.Image.FromStream(req.GetResponse().GetResponseStream());
            img.Save(strImageSavePath);
            return strImageHttpPath;
        }

        
    }
}
